import { isArray } from '@/utils/is';
import { TableColumnData } from '@arco-design/web-vue';
import { onMounted, reactive, ref } from 'vue';
import { hookResult } from './bindResult';

export interface PaginationTableProps {
  current?: number;
  pageSize?: number;
  /* 在页面挂载时自动调用接口查询 */
  immediate?: boolean;
  apiFun: (params: any) => Promise<any>;
  transformData?: (data: any) => any;
  getQueryParams?: () => any;
  rowKey?: string;
  columns?: TableColumnData[];
  fakePage?: boolean;
  onSuccess?: (data: any) => void;
  rowSelection?: any;
}

const arrIsEmpty = (arr: any[]) => {
  if (!arr) {
    return true;
  }

  if (isArray(arr)) {
    if (arr.length === 0) {
      return true;
    }
    return false;
  }

  return true;
};

export function usePaginationTable<T = any>(prop: PaginationTableProps) {
  const {
    immediate = true,
    apiFun,
    current = 1,
    pageSize = 10,
    transformData,
    getQueryParams,
    rowKey,
    columns,
    fakePage = false,
    onSuccess,
    rowSelection,
  } = prop;

  const loading = ref(false);

  const errorMsg = ref('');

  const isEmpty = ref(true);

  const dataSource = ref<T[]>([]);

  const paginationData = reactive({
    current,
    pageSize,
    total: 0,
    showTotal: true,
  });

  function queryTableData() {
    let queryParams = {
      page: paginationData.current,
      pageSize: paginationData.pageSize,
    };
    if (getQueryParams) {
      const otherParams = getQueryParams();
      queryParams = {
        ...queryParams,
        ...otherParams,
      };
    }
    loading.value = true;
    return apiFun(queryParams)
      .then((result) => {
        const data = fakePage ? result : result.list;

        if (transformData) {
          dataSource.value = transformData(data);
        } else {
          dataSource.value = data;
        }

        paginationData.total = fakePage ? data.length : result.total;

        if (arrIsEmpty(dataSource.value)) {
          errorMsg.value = '暂无数据';
          isEmpty.value = true;
        } else {
          errorMsg.value = '';
          isEmpty.value = false;
        }

        if (onSuccess) {
          onSuccess(dataSource.value);
        }

        return result;
      })
      .catch((err) => {
        errorMsg.value = err.message;
        dataSource.value = [];
        isEmpty.value = true;
      })
      .finally(() => {
        loading.value = false;
      });
  }

  onMounted(() => {
    if (immediate) {
      queryTableData();
    }
  });

  function resetPage() {
    paginationData.current = 1;
    paginationData.pageSize = pageSize;
  }

  function reload() {
    resetPage();
    return queryTableData();
  }

  function onPageChange(page: number) {
    paginationData.current = page;
    if (fakePage) {
      return;
    }
    queryTableData();
  }

  function onPageSizeChange(size: number) {
    paginationData.pageSize = size;
    if (fakePage) {
      return;
    }
    queryTableData();
  }

  return hookResult(
    {
      execute: queryTableData,
      refresh: queryTableData,
      resetPage,
      reload,
      loading,
    },
    {
      loading,
      pagination: paginationData,
      data: dataSource,
      emptyText: errorMsg,
      isEmpty,
      rowKey,
      columns,
      onPageChange,
      onPageSizeChange,
      pageEvent: {
        onPageChange,
        onPageSizeChange,
      },
      rowSelection,
    }
  );
}

export type TPaginationTableResult<T> = ReturnType<
  typeof usePaginationTable<T>
>;
